﻿using System;
using System.Data;
using DataCenter.Interface;
using DataCenter.Interface.Model;
using System.Data.SqlClient;
using System.Diagnostics;

namespace DataCenter.Component.Source
{
    public class SqlSource : ISource, IDbProvider
    {
        public SqlSource(SqlSourceEntity entity)
        {
            this._Entity = entity;
        }
        private SqlSourceEntity _Entity;

        private string connectionString;
        private SqlConnection connection;
        private SqlCommand command;
        private SqlDataAdapter adapter;
        private SqlTransaction transaction;

        #region IComponent Members

        public bool Initialize()
        {
            try
            {
                SqlConnectionStringBuilder cnStrBuilder = new SqlConnectionStringBuilder();
                cnStrBuilder.DataSource = _Entity.DataSource;
                cnStrBuilder.InitialCatalog = _Entity.InitialCatalog;
                if (_Entity.IntegratedSecurity)
                    cnStrBuilder.IntegratedSecurity = _Entity.IntegratedSecurity;
                else
                {
                    cnStrBuilder.UserID = _Entity.UserId;
                    cnStrBuilder.Password = _Entity.Password;
                }
                cnStrBuilder.Pooling = false;

                connectionString = cnStrBuilder.ConnectionString;
                this.Open();

                return true;
            }
            catch (Exception ex)
            {
                return Logger.GetInstance().Error("初始化数据库连接失败", ex);
            }            
        }

        #endregion

        #region IDataSource Members

        public IDataReader GetReader(string sqlString)
        {
            command.CommandText = sqlString;
            command.CommandType = CommandType.Text;
            return command.ExecuteReader();
        }

        public void Destory()
        {
            this.Close();
        }

        #endregion

        #region IDbProvider Members

        public string ConnectionString
        {
            get { return connectionString; }
            set { connectionString = value; }
        }

        public IDbConnection Connection
        {
            get { return connection; }
            set { connection = (SqlConnection)value; }
        }

        public IDbCommand Command
        {
            get { return command; }
            set { command = (SqlCommand)value; }
        }

        public IDbDataAdapter Adapter
        {
            get
            {
                if (adapter == null)
                    adapter = new SqlDataAdapter(command);
                return adapter;
            }
            set { adapter = (SqlDataAdapter)value; }
        }

        public void Open()
        {
            if (string.IsNullOrEmpty(connectionString))
                throw new NullReferenceException("Property ConnectionString is Null.");

            if (connection != null && connection.State == ConnectionState.Open)
                return;

            connection = new SqlConnection(connectionString);
            connection.Open();

            command = new SqlCommand();
            command.Connection = connection;
        }

        public void Close()
        {
            Dispose();
        }

        public void BeginTransaction()
        {
            transaction = connection.BeginTransaction();
            command.Transaction = transaction;
        }

        public void RollBack()
        {
            if (transaction != null)
            {
                transaction.Rollback();
                command.Transaction = null;
                transaction.Dispose();
            }
        }

        public void Commit()
        {
            if (transaction != null)
            {
                transaction.Commit();
                command.Transaction = null;
                transaction.Dispose();
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            if (adapter != null)
            {
                adapter.Dispose();
                adapter = null;
            }
            if (transaction != null)
            {
                transaction.Dispose();
                transaction = null;
            }
            if (command != null)
            {
                command.Dispose();
                command = null;
            }
            if (connection != null)
            {
                if (connection.State == ConnectionState.Open)
                    connection.Close();
                connection.Dispose();
                connection = null;
            }

            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
